package ch.penas.business.service;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.faces.model.SelectItem;
import javax.persistence.Query;

import ch.penas.business.dom.Competence;
import ch.penas.business.dom.Formateur;
import ch.penas.business.dom.FormateurCompetence;

/** @author Daniel */
public class CompetenceServiceImpl extends CompetenceAbstractMYSQL implements
             CompetenceService, Serializable {

    /** Serialisation de la class pour une question de securiter. */
    private static final long serialVersionUID = -6797092500849314538L;

    private Competence competence;

    private FormateurCompetenceServiceImpl mFormateurCompetenceServiceImpl;

    /** Liste des competences. */
    private List<Competence> mCompetenceList;

    /** Liste des competences lier a un utilisateur. */
    private List<Competence> mCompetenceListSearch;

    /**  Permet de reguler le pasage de methode.*/
    private boolean isTrue = true;

    /** Constructeur par défaut de la class CompetenceServiceImpl. */
    public CompetenceServiceImpl() {
        this.mCompetenceList = new ArrayList<Competence>();
        this.mCompetenceListSearch = new ArrayList<Competence>();
        this.competence = new Competence();
        this.mFormateurCompetenceServiceImpl = new FormateurCompetenceServiceImpl();
    }

    /** Permet d'afficher les competence lier au utilisateur.
     *
     * @return mCompetenceListSearch est egale à
     * la liste des competence lier au utilisateur
     */
    public final List<Competence> getAllCompetenceSearch() {
        return this.mCompetenceListSearch;
    }

    /** Permet d'afficher le nombre de competence existant.
    *
    * @return le nombre de competence
    */
   public final int getNbCompetence() {
       Object resultQuery;
       try {
           initFixture();
       } catch (Exception e) {
           e.printStackTrace();
       }
       getEntityTransaction().begin();

       Query query = getEntityManager().createQuery(
               "SELECT COUNT(c.titre) FROM Competence c");

       resultQuery = query.getSingleResult();

       getEntityTransaction().commit();

       try {
           closeEntityManager();
       } catch (SQLException e) {
           e.printStackTrace();
       }
       return Integer.parseInt(resultQuery.toString());
   }

    /** Permet d'afficher les competences.
     *
     * @return la liste des competences
     */
    public final List<Competence> getAll() {
        if (this.getIsTrue()) {
        try {
            initFixture();
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.mCompetenceList.removeAll(mCompetenceList);
        getEntityTransaction().begin();

        Query query = getEntityManager().createQuery(
                "SELECT f FROM Competence f");

        @SuppressWarnings("unchecked")
        List<Competence> b = query.getResultList();
        for (Competence a : b) {
            this.addRecherche(a);
        }
        getEntityTransaction().commit();

        try {
            closeEntityManager();
        } catch (SQLException e) {
            e.printStackTrace();
        }
            this.setIsTrue(false);
        }
        return this.mCompetenceList;
    }

    /** Permet de modifier une competence de la base de donnée SQL.
     *
     * @param mCompetenceUpd est egale a une competence
     * a modifier de la base de donnée SQL
     */
    public final void update(final Competence mCompetenceUpd) {
        try {
            initFixture();

            getEntityTransaction().begin();
            Competence genre = getEntityManager().find(
            Competence.class, mCompetenceUpd.getIdCompetence());

            genre.setTitre(mCompetenceUpd.getTitre());

            getEntityTransaction().commit();

            closeEntityManager();
            this.setIsTrue(true);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /** Permet d'ajouter des competence a la base de donnée SQL.
     *
     * @param mCompetenceAdd est egal a une competence
     * a ajouter a la base de donnée SQL
     */
    public final void add(final Competence mCompetenceAdd) {
        try {
            initFixture();

            getEntityTransaction().begin();
            getEntityManager().persist(mCompetenceAdd);
            getEntityTransaction().commit();

            closeEntityManager();
            this.setIsTrue(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** Permet de supprimer des competence de la base de donnée SQL.
     *
     * @param mCompetenceDel est egale a une competence
     * a supprimer de la base de donnée SQL
     */
    public final void del(final Competence mCompetenceDel) {
        try {
            initFixture();

            getEntityTransaction().begin();
            Competence userx = getEntityManager().find(
            Competence.class, mCompetenceDel.getIdCompetence());
            getEntityManager().remove(userx);
            getEntityTransaction().commit();

            closeEntityManager();
            this.setIsTrue(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**  Permet d'afficher la liste des competence lier a un utilisateur.
     *
     * @param mUtilisateur est egale a un Formateur
     */
   public final void info(final Formateur mUtilisateur) {
       try {
           initFixture();
       } catch (Exception e) {
           e.printStackTrace();
       }
       this.mCompetenceListSearch.removeAll(mCompetenceListSearch);
       getEntityTransaction().begin();
       Query query = getEntityManager().createQuery(
       "SELECT c FROM Competence c,"
       + "FormateurCompetence fc WHERE fc.idFormateur='"
       + mUtilisateur.getIdUtilisateur() + "'"
       + "AND fc.idCompetence= c.idCompetence");

       @SuppressWarnings("unchecked")
       List<Competence> b = query.getResultList();
       for (Competence a : b) {
           this.addRechercheCompetence(a);
       }
       getEntityTransaction().commit();

       try {
           closeEntityManager();
       } catch (SQLException e) {
           e.printStackTrace();
       }
   }

   public final List<SelectItem> getValuesIdCompetence() {
       try {
           initFixture();
       } catch (Exception e) {
           e.printStackTrace();
       }
       List<SelectItem> idCompetence = new ArrayList<SelectItem>();
       idCompetence.removeAll(idCompetence);
       getEntityTransaction().begin();

       Query query = getEntityManager().createQuery("SELECT c FROM Competence c");

       @SuppressWarnings("unchecked")
       List<Competence> b = query.getResultList();
       for (Competence a : b) {
           this.competence = a;
           idCompetence.add(new SelectItem(competence.getIdCompetence(),competence.getTitre()));
       }
       getEntityTransaction().commit();

       try {
           closeEntityManager();
       } catch (SQLException e) {
           e.printStackTrace();
       }
       return idCompetence;
   }

    /** Permet d'ajouter des competences a la liste des competences.
     *
     * @param mCompetenceAddSearchList est egal a une competence
     * a ajouter a la liste des competences
     */
    public final void addRecherche(
            final Competence mCompetenceAddSearchList) {
        this.mCompetenceList.add(mCompetenceAddSearchList);
    }

    /** Permet d'ajouter des competences lier a l'utilisateur
     *  a la liste des competences.
     *
     * @param mCompetenceAddSearchList est egal
     * a une competence lier a un utilisateur
     * a ajouter a la liste des competences
     */
    public final void addRechercheCompetence(
            final Competence mCompetenceAddSearchList) {
        this.mCompetenceListSearch.add(mCompetenceAddSearchList);
    }

    /** Permet de recupéré isTrue.
     *
     * @return isTrue est egale a isTrue
     */
    public final boolean getIsTrue() {
        return isTrue;
    }
    /** Permet de modifier la valeur de isTrue.
     *
     * @param aIsTrue est egale a isTrue
     */
    public final void setIsTrue(final boolean aIsTrue) {
        this.isTrue = aIsTrue;
    }


}